import sys
import time
import pandas as pd
from contract_market.utils.api import xt_api
from contract_market.strategy.image.runtime_params import wait_params, optimal_params


class Optimal(object):

    def __init__(self, cfg, symbol, transcation_type) -> None:
        self.cfg = cfg
        self.symbol = symbol
        self.transcation_type = transcation_type
        xt_api.init_client(symbol, transcation_type)
        self.last_timing = int(time.time())
        self.last_balance = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')

    @property
    def unit(self):
        base, quote = self.symbol.split('_')
        return quote if self.transcation_type=='um' else base

    @property
    def fund(self):
        fund = self.cfg.values('max_fund')
        return fund

    def balance_density(self):
        coef = 0
        wallet_balance = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')
        pnl = self.fund - wallet_balance
        if pnl > 0:
            coef = round(pnl/self.fund*optimal_params.get('balance_density').get('max_ratio'), 4)
        return coef
    
    def balance_spread(self):
        coef = 0
        wallet_balance = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')
        pnl = self.fund - wallet_balance
        if pnl > 0:
            coef = round(pnl/self.fund*optimal_params.get('balance_spread').get('max_ratio'), 4)
        return coef

    def position_density(self):
        long_coef, short_coef = 0, 0
        pos = xt_api.position(self.symbol)
        pos = pd.DataFrame(pos)
        lp = float(pos[pos.positionSide=='LONG'].isolatedMargin.squeeze())
        sp = float(pos[pos.positionSide=='SHORT'].isolatedMargin.squeeze())
        diff = lp-sp
        if diff > 0:
            long_coef = round(diff/self.fund*optimal_params.get('position_density').get('max_ratio'), 4)
        else:
            short_coef = round(abs(diff)/self.fund*optimal_params.get('position_density').get('max_ratio'), 4)
        return long_coef, short_coef

    def position_spread(self):
        coef, side = 0, 'LONG'
        position = xt_api.position(symbol=self.symbol, method='api')
        position = pd.DataFrame(position)
        position = position.astype({'realizedProfit': float})
        pos_pnl = position.realizedProfit.sum().round(2)
        if pos_pnl < 0:
            coef = round(abs(pos_pnl)/self.fund*optimal_params.get('position_spread').get('max_ratio'), 4)
            side = position.sort_values('realizedProfit').iloc[0].positionSide
        return coef, side

    def episode_loss(self):
        def reset_state():
            self.last_time = int(time.time())
            self.last_balance = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')
        fund = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')
        params = optimal_params.get('episode_loss')
        eps = params.get('time')
        max_loss = params.get('max_loss')
        diff_time = int(time.time()) - self.last_timing
        if diff_time <= eps:
            pnl = self.last_balance - fund
            if pnl > fund*max_loss:
                return diff_time
        else:
            reset_state()
        return 0
        
    def balance_loss(self):
        wallet_balance = xt_api.balance(method='api', unit=self.unit, kind='walletBalance')
        max_fund = self.cfg.values('max_fund')
        init_fund = self.cfg.values('init_fund')
        pnl = init_fund - wallet_balance
        if pnl > max_fund*optimal_params.get('balance_loss').get('max_loss'):
            print('wuwu~, 钱都被亏完了')
            return False
        return True
